package com.blq.developtools.view;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PathEffect;
import android.graphics.Rect;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import com.blq.developtools.R;
import com.blq.developtools.bean.ViewTreeBean;
import com.blq.developtools.interfaces.OnLayoutStructureSelectListener;

import java.util.ArrayList;
import java.util.List;

import blq.ssnb.snbutil.SnbLog;

/**
 * <pre>
 * ****************************************************************
 * 文件名称:LayoutStructureView.java
 * 作 者:SSNB
 * 创建时间:2024/5/22
 * 文件描述:
 * 注意事项:
 * 版权声明:Copyright (C) 2015-2025 杭州中焯信息技术股份有限公司
 * 修改历史:2024/5/22 1.00 初始版本
 * ****************************************************************
 * </pre>
 */
public class LayoutStructureView extends View {
    public LayoutStructureView(Context context) {
        this(context, null);
    }

    public LayoutStructureView(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public LayoutStructureView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        this(context, attrs, defStyleAttr, 0);
    }

    public LayoutStructureView(Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
        onInit();
    }

    private ViewTreeBean rootBean;
    private ViewTreeBean selectLayoutBean;

    private int backgroundColor;
    private int selectBorderColor;
    private Paint framePaint;
    private Paint selectPaint;

    private Path mPath;
    private Path selectPath;
    private RectF selectRectF;

    private Path drawPath;

    private OnLayoutStructureSelectListener onLayoutStructureSelectListener;

    private void onInit() {
        backgroundColor = getResources().getColor(R.color.transparent_alpha_40);
        selectBorderColor = Color.RED;
        framePaint = new Paint();
        framePaint.setColor(Color.YELLOW);
        framePaint.setStyle(Paint.Style.STROKE);
        framePaint.setStrokeWidth(3);

        selectPaint = new Paint();
        selectPaint.setColor(backgroundColor);
        selectPaint.setStrokeWidth(3);

        mPath = new Path();
        drawPath = new Path();

        selectRectF = new RectF();
        selectPath = new Path();
        selectPath.setFillType(Path.FillType.EVEN_ODD);
    }

    @Override
    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
        super.onLayout(changed, left, top, right, bottom);
        mPath.reset();
        mPath.addRect(0, 0, getWidth(), getHeight(), Path.Direction.CW);
    }

    @Override
    protected void onDraw(@NonNull Canvas canvas) {
        super.onDraw(canvas);
        drawRect(rootBean, canvas, false);
        drawSelectView(canvas);
    }

    private void drawSelectView(Canvas canvas) {
        if (selectLayoutBean != null) {
            selectRectF.set(selectLayoutBean.getInScreenLocation());
            selectPath.reset();
            selectPath.addRect(selectRectF, Path.Direction.CW);
            drawPath.op(mPath, selectPath, Path.Op.DIFFERENCE);
            resetSelectPaint(false);
            canvas.drawPath(drawPath, selectPaint);
            resetSelectPaint(true);
            canvas.drawRect(selectRectF, selectPaint);
        } else {
            canvas.drawPath(mPath, selectPaint);
        }
    }

    private void resetSelectPaint(boolean isFrame) {
        if (isFrame) {
            selectPaint.setColor(selectBorderColor);
            selectPaint.setStyle(Paint.Style.STROKE);
        } else {
            selectPaint.setColor(backgroundColor);
            selectPaint.setStyle(Paint.Style.FILL);
        }
    }

    private void drawRect(ViewTreeBean bean, Canvas canvas, boolean isSelect) {
        if (bean != null) {
            canvas.drawRect(bean.getInScreenLocation(), framePaint);
            for (ViewTreeBean childBean : bean.getChildView()) {
                drawRect(childBean, canvas, isSelect);
            }
        }
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        if ((event.getAction() & MotionEvent.ACTION_MASK) == MotionEvent.ACTION_DOWN) {
            float x = event.getRawX();
            float y = event.getRawY();
            SnbLog.e(">>>点击位置：" + x + "," + y);
//            doFind(x, y, rootBean);
            List<ViewTreeBean> containsBeans = new ArrayList<>();
            findIn(x, y, rootBean, containsBeans);
            if (onLayoutStructureSelectListener != null) {
                onLayoutStructureSelectListener.onSelect(containsBeans);
            }
        }
        return super.onTouchEvent(event);
    }

    private void doFind(float x, float y, ViewTreeBean bean) {
//        SnbLog.e(">>>>find:level:"+bean.layerLevel
//                +",point(x,y):("+x+","+y+")"
//                +",view(rect):"+bean.inScreenLocation.toString()
//                +",isIn:"+bean.inScreenLocation.contains((int) x, (int) y));
        if (bean != null) {
            if (!bean.getChildView().isEmpty()) {
                for (ViewTreeBean childBean : bean.getChildView()) {
                    doFind(x, y, childBean);
                }
            }
        }

    }

    private boolean findIn(float x, float y, ViewTreeBean bean, List<ViewTreeBean> containsList) {
        if (bean != null) {
//            SnbLog.e(">>>>find:level:"+bean.layerLevel
//                    +",point(x,y):("+x+","+y+")"
//                    +",view(rect):"+bean.inScreenLocation.toString()
//                    +",isIn:"+bean.inScreenLocation.contains((int) x, (int) y));
            if (bean.getInScreenLocation().contains((int) x, (int) y)) {
                if (bean.getChildView().isEmpty()) {
                    containsList.add(bean);
                    return true;
                } else {
                    boolean isChildIn = false;
                    for (ViewTreeBean childBean : bean.getChildView()) {
                        boolean isIn = findIn(x, y, childBean, containsList);
                        if (isIn) {
                            isChildIn = true;
                        }
                    }
                    if (!isChildIn) {
                        containsList.add(bean);
                        return true;
                    } else {
                        return false;
                    }
                }
            } else {
                return false;
            }
        }
        return false;
    }

    public void setLayoutTree(ViewTreeBean bean) {
        rootBean = bean;
        invalidate();
    }

    public void setSelectLayout(ViewTreeBean bean) {
        selectLayoutBean = bean;
        invalidate();
    }

    public ViewTreeBean getSelectLayout() {
        return selectLayoutBean;
    }

    public void setOnLayoutStructureSelectListener(OnLayoutStructureSelectListener onLayoutStructureSelectListener) {
        this.onLayoutStructureSelectListener = onLayoutStructureSelectListener;
    }
}
